﻿using System.Collections;
using System.Collections.Generic;
using UnityEngine;

//方格的状态，包括“空方格”，“被占用方格(寻路上视为可通过)”，“被占用方格(寻路上视为不可通过)”
public enum BlockType
{
    Base, Empty, Occupied, Hard
}

public enum BuildingType
{
    None, Shop, BaseCrossbow, Ruin, Marsh, Heat, BaseCannon, Production, DarkFrameCrossbow, Nut, WhiteAngelCrossbow, Muddy, FireAngelCannon, SoulCannon
}

public enum TerrainType
{
    None, Breakable, Unbreakable, Lava
}

//寻路结果返回时使用的tag
public enum RoadSelectTag
{
    Normal, Goal, Tower, ERROR
}

//寻路结果结构体
public struct RoadSelectResult
{
    int x, y;
    RoadSelectTag tag;
    public RoadSelectResult(int x = -1, int y = -1, RoadSelectTag t = RoadSelectTag.ERROR)
    {
        this.x = x;
        this.y = y;
        this.tag = t;
    }
    public Vector2Int Pos()
    {
        return new Vector2Int(x, y);
    }
    public RoadSelectTag Tag()
    {
        return tag;
    }
};


public static class Function
{
    public static Vector2Int WorldPosToLogicPos(float x, float y)
    {
        return new Vector2Int((int)System.Math.Floor((x - ConstOfMap.originPos.x) / ConstOfMap.xGap + 0.5), (int)System.Math.Floor((y - ConstOfMap.originPos.y) / ConstOfMap.yGap + 0.5));
    }
    public static Vector2Int WorldPosToLogicPos(Vector2 pos)
    {
        return WorldPosToLogicPos(pos.x, pos.y);
    }
    public static Vector2 LogicPosToWorldPos(int x, int y)
    {
        return new Vector2(ConstOfMap.originPos.x + ConstOfMap.xGap * x, ConstOfMap.originPos.y + ConstOfMap.yGap * y);
    }
    public static Vector2 LogicPosToWorldPos(Vector2Int pos)
    {
        return LogicPosToWorldPos(pos.x, pos.y);
    }
    public static bool OutOfRange(int x, int y)
    {
        return x < 0 || y < 0 || x >= ConstOfMap.width || y >= ConstOfMap.height;
    }
    public static bool OutOfRange(Vector2Int pos)
    {
        return OutOfRange(pos.x, pos.y);
    }
    public static int LogicDistance(Vector2Int a, Vector2Int b)
    {
        return (int)System.Math.Abs(a.x - b.x) + System.Math.Abs(a.y - b.y);
    }
    public static float Distance(Vector2 a,Vector2 b)
    {
        return (a - b).magnitude;
    }
    public static float DistanceIgnoreZ(Vector3 a, Vector3 b)
    {
        Vector2 aa = new Vector2(a.x, a.y);
        Vector2 bb = new Vector2(b.x, b.y);
        return (aa - bb).magnitude;
    }
    public static float LengthIgnoreZ(Vector3 a)
    {
        return Mathf.Sqrt((a.x * a.x) + (a.y * a.y));
    }
    public static int GetTargetLayerMask(Identity identity)
    {
        if (identity == Identity.aibo)
            return LayerMask.GetMask("Enemy");
        if (identity == Identity.enemy)
            return LayerMask.GetMask("Tower", "Player");
        if (identity == Identity.neutral)
            return LayerMask.GetMask("Tower", "Player", "Enemy");
        return 0;
    }

    public static float GetRadIgnoreZ(Vector3 a,Vector3 b)
    {
        Vector3 offset = (a - b).normalized;
        return Mathf.Atan2(offset.y, offset.x);
    }

    public static float GetDegIgnoreZ(Vector3 a, Vector3 b)
    {
        return GetRadIgnoreZ(a, b) * Mathf.Rad2Deg; 
    }

    public static float DistanceBetweenRad(float a,float b)
    {
        float t = a - b;
        while (t < 0) t += Mathf.PI * 2;
        while (t >= Mathf.PI * 2) t -= Mathf.PI * 2;
        if (t > Mathf.PI)
            t = Mathf.PI * 2 - t;
        return t;
    }
}

public enum ResourceType
{
    None, Money
}

public enum AttackActionState
{
    Cooling, Ready, Front, Attacking, After
}

public enum AttackMode
{
    Immediate = 0,
    Continued = 1,
    Missile = 2,
    Parabola = 3
}

public enum AttackType
{
    Single  = 0,
    Aoe = 1
}

public class ConstOfMap
{
    public readonly static Vector3 originPos = new Vector3(0, 0, 0);
    public readonly static Vector2Int ERRORPOS = new Vector2Int(-1, -1);
    public static float xGap = 0.64f;
    public static float yGap = 0.64f;
    public static int width = 50;
    public static int height = 30;
    public static int operateRange = 1;
    public static Vector2Int initEnterPos = new Vector2Int(1, height / 2);
    public static Vector2Int initPlayerPos = new Vector2Int(width / 2 - 1, height / 2);
    public static Vector2Int initGoalPos = new Vector2Int(width / 2, height / 2);
    public static int FLOORMAX = 36;
    public static int MASKMAX = 16;
    public static float MOUSEUNMOVE = 0.5f;
    public static int EVENTMAX = 3;
    public static int EVENTRATE = 15;

    public static uint seed = 0;
    public static bool setseed = false;

    public static bool loadgame = false;
    public static Save save;

    public static readonly int[] hardlist = new int[18] { 1, 1, 1, 1, 1, 1, 1, 1, 1, 1, 2, 2, 2, 2, 2, 3, 3, 4 };
    public static readonly int rarerate = 5;
    public static readonly int lavarate = 20;
    public static readonly int heatrate = 20;
    public static readonly int muddyrate = 15;
}


//敌我身份判别
public enum Identity
{
    enemy = 0,
    aibo = 1,
    neutral = 2
}


public class Tag
{
    public static bool goalIsLocked = false; //终点锁:0是没被锁，1是被锁
    public static float mouseDelay = 0;
    public static bool playerPause = false;
    public static bool gameover = false;
    
}

public enum MaskType//
{
    FULL, //0000
    DR,//0001
    DL,//0010
    D,//0011
    UR,//0100
    R,//0101
    UR_DL,//0110
    NON_UL,//0111
    UL,//1000
    UL_DR,//1001
    L,//1010
    NON_UR,//1011
    U,//1100
    NON_DL,//1101
    NON_DR,//1110
    EMPTY//1111
}

public class ConstOfAnimator
{
    public static string[] AnimatorType = {"Idle", "Walk", "Front", "Attack", "After" };
}


public class ConstOfBuff
{
    //public static string[] BuffType = { "Slow", "EarnMoney", "LevelUp", "Burn", "CatchGoalSlow", "RepeatableAttackIncrease" };
    public enum BuffType
    {
        Slow, EarnMoney, LevelUp, Burn, CatchGoalSlow, RepeatableAttackIncrease, RepeatableMaxHpIncrease
    }
}

public class SoldierData
{
    public int name;
    public float hp;
    public float damage;
    public float attackSpeed;
    public float walkSpeed;
    public int score;
    public SoldierData()
    {
        name = 0;
        hp = 1;
        damage = 1;
        attackSpeed = 1;
        walkSpeed = 1;
        score = 0;
    }
    public SoldierData(int a = 0, float b = 1, float c = 1, float d = 1, float e = 1, int f = 0)
    {
        name = a;
        hp = b;
        damage = c;
        attackSpeed = d;
        walkSpeed = e;
        score = f;
    }
}

//buff的描述类
[System.Serializable]
public class BuffInfo
{
    public int buffIndex;
    public float effect;
    public float duration;
    public BuffInfo()
    {
        buffIndex = 0;
        effect = duration = 0.0f;
    }
    public BuffInfo(int buffIndex, float effect, float duration)
    {
        this.buffIndex = buffIndex;
        this.effect = effect;
        this.duration = duration;
    }
}

public enum ButtonStatus
{
    UP,DOWN,RIGHT,LEFT,NULL
}

public class ConstOfGenetic
{
    public static float weightOfLifeTime = 1f;
    public static float weightOfDamage = 30f;
    public static float weightOfCatchGoal = 500f;
}

public class CostOfLevelUp
{
    public static int[] CostForLevelUp = { 3, 6 };
    public static int[] CostAPForLevelUp = { 4, 4 };
}